package com.x.provider.general.controller.rpc;

import com.x.core.utils.BeanUtil;
import com.x.core.web.api.R;
import com.x.core.web.page.PageList;
import com.x.provider.api.general.model.dto.cms.*;
import com.x.provider.api.general.service.CmsRpcService;
import com.x.provider.api.oss.model.dto.green.ContentGreenResultDTO;
import com.x.provider.general.factory.dto.CmsDTOFactory;
import com.x.provider.general.model.domain.cms.Content;
import com.x.provider.general.model.domain.cms.ItemStatistic;
import com.x.provider.general.model.domain.cms.ItemToggleRelation;
import com.x.provider.general.model.domain.cms.Star;
import com.x.provider.general.service.cms.*;
import com.x.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/rpc/cms")
public class CmsRpcController implements CmsRpcService {

    private final StarService starService;
    private final CommentService commentService;
    private final ItemStatService itemStatService;
    private final CommentStatService commentStatService;
    private final ContentService contentService;
    private final CmsDTOFactory cmsDTOFactory;
    private final ItemToggleRelationService itemToggleRelationService;

    public CmsRpcController(StarService starService,
                            CommentService commentService,
                            ItemStatService itemStatService,
                            CommentStatService commentStatService,
                            ContentService contentService,
                            CmsDTOFactory cmsDTOFactory,
                            ItemToggleRelationService itemToggleRelationService){
        this.starService = starService;
        this.commentService = commentService;
        this.itemStatService = itemStatService;
        this.commentStatService = commentStatService;
        this.contentService = contentService;
        this.cmsDTOFactory = cmsDTOFactory;
        this.itemToggleRelationService = itemToggleRelationService;
    }

    @PostMapping("is/starred")
    @Override
    public R<Boolean> isStarred(@RequestBody StarStatusGetReqDTO isStarred) {
        return R.ok(starService.isStarred(isStarred.getItemType(), isStarred.getItemId(), isStarred.getCustomerId()));
    }

    @PostMapping("star/create")
    @Override
    public R<Boolean> star(@RequestBody StarSaveReqDTO starReqDTO) {
        starService.star(starReqDTO);
        return R.ok();
    }

    @PostMapping("star/list")
    @Override
    public R<List<StarDTO>> listStar(@RequestBody StarListReqDTO reqDTO) {
        List<Star> starList = starService.listStar(reqDTO);
        return R.ok(prepare(starList));
    }

    @PostMapping("star/relation/list")
    @Override
    public R<Map<Long, Integer>> listStarRelation(@RequestBody StarListReqDTO reqDTO) {
        return R.ok(starService.listStarRelation(reqDTO));
    }

    @PostMapping("comment/create")
    @Override
    public R<Void> comment(@RequestBody CommentAddReqDTO commentAddReqDTO) {
        commentService.comment(commentAddReqDTO);
        return R.ok();
    }

    @PostMapping("comment/stat/list")
    @Override
    public R<Map<Long, CommentStatisticDTO>> listCommentStatMap(String idList) {
        return R.ok(BeanUtil.prepare(commentStatService.listCommentStatMap(StringUtil.parse(idList)).values(), CommentStatisticDTO.class).stream()
                .collect(Collectors.toMap(CommentStatisticDTO::getId, item -> item)));
    }

    @PostMapping("item/statistic/list")
    @Override
    public R<Map<Long, ItemStatisticDTO>> listStatMap(@RequestBody ItemStatListReqDTO itemStatListReqDTO) {
        Map<Long, ItemStatistic> result = itemStatService.listItemStatMap(itemStatListReqDTO);
        if (result.isEmpty()){
            return R.ok(new HashMap<>());
        }
        Map<Long, ItemStatisticDTO> dtoMap = new HashMap<>(result.size());
        result.entrySet().forEach(item -> {
            dtoMap.put(item.getKey(), BeanUtil.prepare(item.getValue(), ItemStatisticDTO.class));
        });
        return R.ok(dtoMap);
    }

    @PostMapping("content/my")
    @Override
    public R<PageList<ContentDTO>> listMyContent(@RequestBody ContentMyReqDTO reqDTO) {
        PageList<Content> contentPageList = contentService.listMyContent(reqDTO);
        if (contentPageList.getList().isEmpty()){
            return R.ok(new PageList<>());
        }
        List<ContentDTO> contentDTOList = cmsDTOFactory.prepare(contentPageList.getList(), reqDTO.getOptions());
        return R.ok(PageList.map(contentPageList, contentDTOList));
    }

    @PostMapping("content/my/total/count")
    @Override
    public R<Map<Integer, Integer>> getMyContentTotal(@RequestBody ContentMyTotalReqDTO contentMyTotalReqDTO) {
        return R.ok(contentService.listMyContentTotalCount(contentMyTotalReqDTO));
    }

    @PostMapping("content/by/ids")
    @Override
    public R<List<ContentDTO>> listContentByIds(@RequestBody ContentByIdsReqDTO reqDTO) {
        List<Content> contents = contentService.listContent(reqDTO.getIdList());
        List<ContentDTO> result = cmsDTOFactory.prepare(contents, reqDTO.getOptions());
        return R.ok(result);
    }

    @PostMapping("content/create")
    @Override
    public R<Long> createContent(@RequestBody ContentCreateReqDTO contentCreateReqDTO) {
        return R.ok(contentService.createContent(contentCreateReqDTO));
    }

    @PostMapping("content/delete")
    @Override
    public R<Void> deleteContent(@RequestBody ContentDeleteReqDTO reqDTO) {
        contentService.deleteContent(reqDTO.getIdList(), reqDTO.getCustomerId());
        return R.ok();
    }

    @PostMapping("item/toggle/relation/list")
    @Override
    public R<PageList<ItemToggleRelationDTO>> listItemToggleRelation(@RequestBody ItemToggleRelationListReqDTO reqDTO) {
        PageList<ItemToggleRelation> result = itemToggleRelationService.list(reqDTO);
        return R.ok(result.map(BeanUtil.prepare(result.getList(), ItemToggleRelationDTO.class)));
    }

    @PostMapping("item/toggle/relation/save")
    @Override
    public R<ItemToggleRelationDTO> toggleRelation(@RequestBody ItemToggleRelationSaveReqDTO req) {
        ItemToggleRelation result = itemToggleRelationService.toggleRelation(req);
        return R.ok(BeanUtil.prepare(req, ItemToggleRelationDTO.class));
    }

    private List<StarDTO> prepare(List<Star> source){
        return BeanUtil.prepare(source, StarDTO.class);
    }

    @PostMapping("review/notify")
    public R<Void> onVodContentReview(@RequestBody ContentGreenResultDTO contentReviewResultDTO){
        contentService.onContentReview(contentReviewResultDTO);
        return R.ok();
    }
}
